package cn.szzsi.business.controller.admin;

import cn.szzsi.business.validator.BusinessRoleValidator;
import cn.szzsi.common.bean.dto.CheckTreeNode;
import cn.szzsi.common.util.CommonUtil;
import cn.szzsi.common.util.EHcacheUtil;
import cn.szzsi.model.*;
import com.jfinal.aop.Before;
import com.jfinal.kit.Ret;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jfinal.plugin.ehcache.CacheKit;
import com.jfinal.plugin.ehcache.EhCachePlugin;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * Created by yuanzheng on 2016/9/23.
 */
public class RoleController extends BaseAdminController<Role> {
    private Role role;
    private String shopId;
    // 列表
    public void list() {
        shopId=getAttr("shopId");
        setAttr("roleList", Role.dao.getByUid(shopId));
        render(CommonUtil.TEMPLATE_PATH+"/business/role/role_list.html");
    }
    //ajax list
    public void ajaxlist(){
        shopId=getAttr("shopId");
        List<Role> lpa = Role.dao.find("select * from sys_role where uid = ? order by createDate desc",shopId);
        renderJson(lpa);
    }

    // 添加
    public void add() {
        render(CommonUtil.TEMPLATE_PATH+"/business/role/role_input.html");
    }

    // 编辑
    public void edit() {
        String id = getPara("id","");
        if (StrKit.notBlank(id)){
            setAttr("role", Role.dao.findById(id));
        }
        render(CommonUtil.TEMPLATE_PATH+"/business/role/role_input.html");
    }

    // 保存
    //@Before(BusinessRoleValidator.class)
    public void save() {
        shopId=getAttr("shopId");
        role = getModel(Role.class);
        role.set("uid",shopId);
        saved(role);
        renderJson(Ret.ok("info","添加成功!").set("url","list"));
    }

    //角色的资源管理
    public void resource(){
        shopId=getAttr("shopId");
        //获取本商户的所有资源
//        List<Resource> lbr = Resource.dao.getByUid(shopId);
//        setAttr("lbr",lbr);
//        setAttr("m",Member.dao.findById(shopId));
        //展示出来
        setAttr("roleId",getPara("roleId"));
        setAttr("checked",true);
        render(CommonUtil.TEMPLATE_PATH+"/business/role/role_resource.html");
    }

    @Before(Tx.class)
    public void resourceRoleSet(){
        shopId=getAttr("shopId");
        String roleId = getPara("roleId");//角色id
        String resourceId = getPara("resourceId");//资源id(可能是动作ID)
        boolean checked = getParaToBoolean("checked");//是否选中
        boolean isParent=getParaToBoolean("isParent");//是否是树的父级

        boolean isExsit = Action.dao.isExsitById(resourceId);//资源-动作是否存在
       // boolean isExsit = ActionResource.dao.isExsitByActionId(resourceId);//资源-动作是否存在
        if(checked){//选中(新增)
            Resource resource= Resource.dao.findById(resourceId);//当前菜单
            if (!isExsit){//不存在,说明该菜单不是动作-资源,而是角色-资源,
                saveRoleResource(roleId,resourceId);//保存角色资源

            }
            if(isParent){//如果是父级菜单
                //判断该父级菜单是否是伪父级菜单(即该菜单下面绑定了动作权限,相当于该菜单是子级菜单)
                List<Action>lars=Action.dao.getByResourceIdAndShopId(resource.getStr("id"),shopId);//查看该菜单是否含有动作权限
                if(lars.size()>0){
                    for(Action ar:lars){
                        ActionRole.dao.saveInfo(ar.getStr("actionId"),ar.getStr("resourceId"),roleId,shopId);
                    }
                    setParentResource(resource,roleId);
                }else{
                    setParentOrChildrenResource(resource,roleId);
                }
            }else{//非父级菜单(1.可能是子级菜单下面的动作资源,2.可能是子级菜单)
                if(isExsit){//如果是子级菜单下面的动作资源,先保存上级所有菜单,再保存 动作-资源-角色信息
                    //若是第一种情况,先根据动作查询子级菜单的resourceId
                    Action action=Action.dao.findById(resourceId);//动作
                    String parentResourceId=action.getStr("resourceId");//动作权限的上级菜单ID(即子菜单ID)

                    if(RoleResource.dao.getByRoleAndResourceId(roleId,parentResourceId)==null){//若子菜单不存在,则保存
                        saveRoleResource(roleId,parentResourceId);//先保存子级菜单
                    }
                    Resource parentResource=Resource.dao.findById(parentResourceId);//子级菜单()
                    setParentResource(parentResource,roleId);//再保存上级菜单
                    ActionRole.dao.saveInfo(resourceId,parentResourceId,roleId,shopId);//保存 动作-资源-角色
                }else{//子级菜单(下面不含有动作资源)
                    setParentResource(resource,roleId);
                }
            }
        }else{//非选中(删除)
            if(isExsit){
                ActionRole arr= ActionRole.dao.getByActionIdAndRoleId(resourceId,roleId);
                if(arr!=null){
                    arr.delete();
                }
            }
            RoleResource.dao.deleteByRoleAndResourceId(roleId,resourceId);//先删除当前菜单
            if(isParent){//如果是父级,将其下面的所有子菜单都删除
                Resource parentRecourse= Resource.dao.findById(resourceId);
                List<Resource> listChildRecourse= Resource.dao.getByPidOrCid(parentRecourse.getStr("id"),shopId);
                for(Resource childRecourse:listChildRecourse){
                    RoleResource.dao.deleteByRoleAndResourceId(roleId,childRecourse.getStr("id"));
                    if(childRecourse.getInt("level")==3){//查看最后一级菜单是否已经绑定了动作权限,如果绑定了,将其删除
                        List<ActionRole>arrList= ActionRole.dao.getByResourceIdAndShopId(childRecourse.getStr("id"),shopId);
                        for(ActionRole arr:arrList){
                            arr.delete();
                        }
                    }
                }
            }
        }

        CacheKit.remove(EHcacheUtil.RESOURCE_MENU,roleId);//清除该角色的缓存
        renderJson(true);
    }

    public void resourceTree(){
        shopId=getAttr("shopId");
        //获取资源的id
        String id = getPara("id");
        String roleId = getPara("roleId");
        List<Resource> lbr = Resource.dao.getByPid(id,shopId);
        List<CheckTreeNode> lctn = new ArrayList<CheckTreeNode>();
        if(lbr.size()==0){//最后一级
            List<Action>list=Action.dao.getByResourceIdAndShopId(id,shopId);//查看最后一级资源是否含有动作权限
            for(Action action:list){
                //如果最后一级资源含有动作权限,将其展示出来
                CheckTreeNode ctn = new CheckTreeNode();
                Action am= Action.dao.findById(action.getStr("id"));
                if(am !=null){
                    ctn.setName(Action.dao.findById(action.getStr("id")).getStr("name"));
                    ctn.setId(action.getStr("id"));
                }

                //如果最后一级资源含有动作权限,并且绑定了该动作权限,应使其处于选中状态
                ActionRole arr= ActionRole.dao.getByActionIdAndRoleId(action.getStr("id"),roleId);
                if(arr!=null){
                    ctn.setChecked(true);
                }else{
                    ctn.setChecked(false);
                }
                ctn.setIsParent(false);
                lctn.add(ctn);
            }
        }else{
            for(Resource br:lbr){
                CheckTreeNode ctn = new CheckTreeNode();
                ctn.setName(br.getStr("name"));
                ctn.setId(br.getStr("id"));

                if(RoleResource.dao.isRoleResourceRalationExsit(br.getStr("id"),roleId)){
                    ctn.setChecked(true);
                }else{
                    ctn.setChecked(false);
                }

                if(Resource.dao.hasChildren(br.getStr("id"))){//父节点
                    ctn.setIsParent(true);
                }else{//子节点
                    //判断子节点是否含有动作权限
                    List<Action> action=Action.dao.getByResourceIdAndShopId(br.getStr("id"),shopId);
                    if(action.size()>0){//含有动作权限,将子节点设为父节点
                        ctn.setIsParent(true);
                    }else{//如果子节点不含有动作权限,则默认原来的子节点
                        ctn.setIsParent(false);
                    }
                }
                lctn.add(ctn);
            }
        }

        renderJson(lctn);
    }



    /**
     * 设置父级的role_resource(针对最后一级资源)
     * @param resource 父级资源对象
     * @param roleId 角色id
     */
    public void setParentResource(Resource resource,String roleId){
        Resource parentResource= Resource.dao.findById(resource.getStr("parent_id"));//父级角色
        Resource pparentResource= Resource.dao.findById(parentResource.getStr("parent_id"));//父父级角色
        RoleResource pbrr = RoleResource.dao.getByRoleAndResourceId(roleId,parentResource.getStr("id"));//父级
        RoleResource ppbrr = RoleResource.dao.getByRoleAndResourceId(roleId,pparentResource.getStr("id"));//父父级
        if(pbrr==null){//如果父级没选择,则改变父级选中状态
            pbrr = new RoleResource();
            pbrr.set("roleId",roleId);
            pbrr.set("resourceId",parentResource.getStr("id"));
            pbrr.set("createDate",new Date());
            pbrr.save();
            if(ppbrr==null){
                ppbrr = new RoleResource();
                ppbrr.set("roleId",roleId);
                ppbrr.set("resourceId",pparentResource.getStr("id"));
                ppbrr.set("createDate",new Date());
                ppbrr.save();
            }

        }
    }

    /**
     *
     * @param resource 当前菜单
     * @param roleId 角色id
     */
    public void setParentOrChildrenResource(Resource resource,String roleId){
        shopId=getAttr("shopId");
        List<Resource> listChildRecourse= Resource.dao.getByPidOrCid(resource.getStr("path"),shopId);
        for(Resource childRecourse:listChildRecourse){
            if(childRecourse.getInt("level")==3){//查看最后一级菜单是否已经绑定了权限,如果绑定了,将其删除
                List<Action>lars=Action.dao.getByResourceIdAndShopId(childRecourse.getStr("id"),shopId);//查看最后一级资源是否含有动作权限
                for(Action a:lars){
                    ActionRole.dao.saveInfo(a.getStr("id"),a.getStr("resourceId"),roleId,shopId);
                }
            }
            RoleResource newChildRoleRecourse=new RoleResource();
            newChildRoleRecourse.set("roleId",roleId);
            newChildRoleRecourse.set("resourceId",childRecourse.getStr("id"));
            newChildRoleRecourse.set("createDate",new Date());
            newChildRoleRecourse.save();
        }
        String parentId=resource.getStr("parent_id");//当前菜单的父级ID
        if(StrKit.notBlank(parentId)){//如果该父级菜单还有父级,将其父级也选中
            Resource parentResource= Resource.dao.findById(parentId);
            RoleResource pbrr = RoleResource.dao.getByRoleAndResourceId(roleId,parentResource.getStr("id"));
            if(pbrr==null){//如果父级没选择,则改变父级选中状态
                pbrr = new RoleResource();
                pbrr.set("roleId",roleId);
                pbrr.set("resourceId",parentResource.getStr("id"));
                pbrr.set("createDate",new Date());
                pbrr.save();
            }
        }
    }

    /**
     * 保存角色资源
     * @param roleId
     * @param resourceId
     */
    public void saveRoleResource(String roleId,String resourceId){
        RoleResource brr = new RoleResource();
        brr.set("roleId",roleId);
        brr.set("resourceId",resourceId);
        brr.set("createDate",new Date());
        brr.save();
    }

    // 更新
    //@Before(BusinessRoleValidator.class)
    public void update() {
        role = getModel(Role.class);
        updated(role);
        renderJson(Ret.ok("info","修改成功!").set("url","list"));
    }

    // 删除
    public void delete() {
        String[] ids = getParaValues("ids");
        if (ids != null && ids.length > 0) {
            for (String id : ids) {
                if (Role.dao.delete(id)) {
                    renderJson(Ret.ok("info","删除成功!"));

                } else {
                    renderJson(Ret.fail("info","删除失败!"));
                }
            }
        } else {
            renderJson(Ret.fail("info","id为空未选中，删除失败!"));
        }
    }
}
